package com.kc.gb.device.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.kc.gb.device.common.adapter.StationAdaptor;
import com.kc.gb.device.common.adapter.dto.basic.station.dto.BasicStationDTO;
import com.kc.gb.device.common.adapter.dto.basic.station.dto.StationLightDTO;
import com.kc.gb.device.common.adapter.dto.basic.station.dto.StationPointDTO;
import com.kc.gb.device.common.adapter.dto.basic.station.enums.LightType;
import com.kc.gb.device.common.dto.I18NException;
import com.kc.gb.device.common.enums.ErrorCode;
import com.kc.gb.device.common.utils.Validators;
import com.kc.gb.device.plugins.ptl.service.PtlHardwareService;
import com.kc.gb.device.plugins.strip.service.StripHardwareService;
import com.kc.gb.device.service.StripAdminService;
import com.kc.gb.device.service.support.dto.StationContainerSlot;
import com.kc.gb.device.service.support.dto.StationContainerSlotArea;
import com.kc.gb.device.service.support.dto.StationContainerSlotLayout;
import com.kc.gb.feign.ptl.support.dtos.AbstractPtlCommand;
import com.kc.gb.feign.ptl.support.dtos.LedCommand;
import com.kc.gb.feign.ptl.support.dtos.LightCommand;
import com.kc.gb.feign.ptl.support.enums.PtlLedOnOff;
import com.kc.gb.feign.ptl.support.enums.PtlLightColor;
import com.kc.gb.feign.ptl.support.enums.PtlLightOnOff;
import com.kc.gb.feign.strip.sopport.dto.StripCommand;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StripAdminServiceImpl implements StripAdminService {

    @Resource
    StationAdaptor stationAdaptor;

    @Resource
    PtlHardwareService iDevicePtlService;

    @Resource
    StripHardwareService iDeviceStripService;


    AtomicBoolean DEBUG_MODE = new AtomicBoolean(false);

    @Override
    public boolean changeMode(boolean isDebugMode){
        DEBUG_MODE.set(isDebugMode);
        return isDebugMode;
    }

    @Override
    public boolean getMode(){
        return DEBUG_MODE.get();
    }

    @Override
    public StationContainerSlotLayout getStationContainerSlotLights(Long warehouseId, String stationCode){
        StationContainerSlotLayout result = new StationContainerSlotLayout();
        log.info("station code {}",stationCode);
        BasicStationDTO stationDTO = stationAdaptor.getBasicStation(warehouseId,stationCode);
        Validators.isTrue(ObjectUtils.isNotEmpty(stationDTO),ErrorCode.STATION_NOT_FOUND,stationCode);
        result.setLightType(ObjectUtils.isEmpty(stationDTO.getLightType())?LightType.ptl:stationDTO.getLightType());
        result.setLayouts(getStationContainerSlotArea(stationDTO));
        return result;
    }

    /**
     * 获取工作站料格灯的相关区域信息
     */
    private List<StationContainerSlotArea> getStationContainerSlotArea(BasicStationDTO stationDTO) {

        Map<String, List<StationLightDTO>> pointLightMap = stationDTO.getLights().stream().collect(Collectors.groupingBy(StationLightDTO::getStationPointCode));
        List<StationContainerSlotArea> result = new ArrayList<>();
        pointLightMap.forEach((pointCode, slotLightsCurrentPoint) -> {
            // 默认为电子标签灯
            LightType lightType = stationDTO.getLightType();
            lightType = ObjectUtils.isEmpty(lightType)?LightType.ptl:lightType;
            // 循环遍历料格灯信息
            slotLightsCurrentPoint.stream().sorted(Comparator.comparing(StationLightDTO::getLineNo));
            int masterLightIndex = 0;
            int masterLightNo = 0;
            List<StationContainerSlot> lights = new ArrayList<>();
            for (StationLightDTO stationLightDTO: slotLightsCurrentPoint){
                // 兼容灯带配置信息
                if(LightType.strip.equals(lightType) && stationLightDTO.getLineNo()==masterLightIndex){
                    masterLightNo = Integer.parseInt(stationLightDTO.getLightCode());
                    continue;
                }
                StationContainerSlot containerSlot = new StationContainerSlot();
                containerSlot.setLightNo(Integer.parseInt(stationLightDTO.getLightCode()));
                containerSlot.setLightIndex(stationLightDTO.getLineNo());
                containerSlot.setEnabled(true);
                lights.add(containerSlot);
            }
            StationContainerSlotArea area = new StationContainerSlotArea();
            area.setPointCode(pointCode);
            area.setLightType(lightType);
            area.setMasterLightIndex(masterLightIndex);
            area.setMasterLightNo(masterLightNo);
            area.setLights(lights);
            result.add(area);
        });
        sortStationPointsByLeftRight(stationDTO,result);
        log.info("result {}", JSON.toJSONString(result));
        return result;
    }

    /**
     * 设置点位的左右排序，左边点位排在前面
     * @param stationDTO
     * @param result
     */
    private void sortStationPointsByLeftRight(BasicStationDTO stationDTO, List<StationContainerSlotArea> result) {
        if(CollectionUtil.isEmpty(result)){
            return;
        }
        result.sort(new Comparator<StationContainerSlotArea>() {
            @Override
            public int compare(StationContainerSlotArea o1, StationContainerSlotArea o2) {
                Map<String, StationPointDTO.StationPointLayoutPosition> leftRight = new HashMap<>();
                CollectionUtils.emptyIfNull(stationDTO.getStationPoints()).stream().forEach(x->{
                    leftRight.put(x.getPointCode(),x.getLayoutPosition());
                });
                String pointCode1 = o1.getPointCode();
                String pointCode2 = o2.getPointCode();
                StationPointDTO.StationPointLayoutPosition la = leftRight.get(pointCode1);
                StationPointDTO.StationPointLayoutPosition lb = leftRight.get(pointCode2);
                if (StationPointDTO.StationPointLayoutPosition.left.equals(la)){
                    return -1;
                }
                if (StationPointDTO.StationPointLayoutPosition.right.equals(la)){
                    return 1;
                }
                return 0;
            }
        });
    }

    @Override
    public void press(boolean inDebugMode, boolean isMaster, boolean isOn,int lightNo){
        log.info("strip press inDebugMode {} isMaster:{} isOn:{} lightNo:{}", inDebugMode,isMaster,isOn,lightNo);
        // 判定当前硬件的运行模式
        if(inDebugMode){
            // 调试模式点亮
            if(!isOn){
                if(isMaster){
                    List<AbstractPtlCommand> commands = new ArrayList<>();
                    commands.add(new LightCommand(lightNo, PtlLightOnOff.LIGHT_ON, PtlLightColor.RED,0));
                    // 生成 1 到 200 之间的随机整数（包含 1 和 200）
                    Random random = new Random();
                    int randomNum = random.nextInt(200) + 1;
                    commands.add(new LedCommand(lightNo, PtlLedOnOff.LED_ON, randomNum));
                    iDevicePtlService.consumeCommands(commands,inDebugMode);
                }else{
                    List<StripCommand> commands = new ArrayList<>();
                    commands.add(new StripCommand(lightNo).turnOn());
                    iDeviceStripService.consumeCommands(commands,inDebugMode);
                }
            }
            // 调试模式关灯
            else{
                if(isMaster){
                    List<AbstractPtlCommand> commands = new ArrayList<>();
                    commands.add(new LightCommand(lightNo).turnOff());
                    commands.add(new LedCommand(lightNo).turnOff().num(0));
                    iDevicePtlService.consumeCommands(commands,inDebugMode);
                }else{
                    List<StripCommand> commands = new ArrayList<>();
                    commands.add(new StripCommand(lightNo).turnOff());
                    iDeviceStripService.consumeCommands(commands,inDebugMode);
                }
            }
        }else{
            // 模拟器模式不允许开灯操作
            if(!isOn){
                throw new I18NException(ErrorCode.PTL_CAN_NOT_OPEN_IN_SIMULATOR);
            }
            // 模拟器模式下关灯操作
            else{
                if(isMaster){
                    // 模拟拍灯事件
                    iDevicePtlService.confirmed(lightNo);
                    // 关灯操作
                    List<AbstractPtlCommand> commands = new ArrayList<>();
                    commands.add(new LightCommand(lightNo, PtlLightOnOff.LIGHT_OFF, PtlLightColor.RED,0));
                    commands.add(new LedCommand(lightNo, PtlLedOnOff.LED_OFF, 0));
                    iDevicePtlService.consumeCommands(commands,inDebugMode);
                }
            }
        }
    }
}
